"""
个人中心页面对象类
"""
import logging
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from tests.page_objects.base_page import BasePage
from selenium.webdriver.support.ui import WebDriverWait


class ProfilePage(BasePage):
    """个人中心页面的页面对象模型"""
    
    # 导航菜单元素
    PROFILE_MENU_ITEM = (By.XPATH, "//li[contains(text(), '个人中心')]")
    PROFILE_MENU_ITEM_ALT = (By.XPATH, "/html/body/div[1]/div/div[1]/div[2]/ul/li[2]")
    
    # 页面元素定位器 - 精确定位
    EDIT_INFO_BUTTON = (By.XPATH, "/html/body/div[1]/div/div[2]/div[2]/div/div[1]/div[1]/div/button")
    SAVE_BUTTON = (By.XPATH, "//button[.//span[contains(text(), '保存')]]")
    CANCEL_BUTTON = (By.XPATH, "//button[.//span[contains(text(), '取消')]]")
    
    # 个人信息表单元素
    USERNAME_INPUT = (By.CSS_SELECTOR, "input[placeholder='请输入用户名']")
    NAME_INPUT = (By.CSS_SELECTOR, "input[placeholder='请输入姓名']")
    EMAIL_INPUT = (By.CSS_SELECTOR, "input[placeholder='请输入邮箱']")
    PHONE_INPUT = (By.CSS_SELECTOR, "input[placeholder='请输入手机号']")
    MALE_RADIO = (By.XPATH, "//span[text()='男']/preceding-sibling::span")
    FEMALE_RADIO = (By.XPATH, "//span[text()='女']/preceding-sibling::span")
    
    # 修改密码表单元素
    OLD_PASSWORD_INPUT = (By.CSS_SELECTOR, "input[placeholder='请输入原密码']")
    NEW_PASSWORD_INPUT = (By.CSS_SELECTOR, "input[placeholder='请输入新密码']")
    CONFIRM_PASSWORD_INPUT = (By.CSS_SELECTOR, "input[placeholder='请再次输入新密码']")
    CHANGE_PASSWORD_BUTTON = (By.XPATH, "//button[contains(text(), '修改密码')]")
    
    # 消息提示元素
    SUCCESS_MESSAGE = (By.CSS_SELECTOR, ".el-message--success")
    ERROR_MESSAGE = (By.CSS_SELECTOR, ".el-message--error")
    
    # 添加表单错误消息定位器
    FORM_ERROR_MESSAGE = (By.CLASS_NAME, "el-form-item__error")
    
    # 个人中心页面URL路径
    PROFILE_PAGE_URL = "back/user/person"
    
    def __init__(self, driver):
        """
        初始化个人中心页面对象
        
        Args:
            driver: WebDriver实例
        """
        super().__init__(driver)
        self.wait = WebDriverWait(self.driver, 10)
    
    def click_profile_menu_item(self):
        """
        点击导航菜单中的个人中心项
        """
        logging.info("点击个人中心菜单项")
        
        # 直接使用JavaScript点击菜单项
        result = self.driver.execute_script("""
        var menuItem = document.evaluate("//li[contains(text(), '个人中心')]", 
                                      document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
        if (!menuItem) {
            menuItem = document.evaluate("/html/body/div[1]/div/div[1]/div[2]/ul/li[2]", 
                                       document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
        }
        if (menuItem) {
            menuItem.click();
            return true;
        }
        return false;
        """)
        
        if result:
            logging.info("成功点击个人中心菜单项")
            return self
        
        # 如果JavaScript点击失败，尝试使用Selenium方法
        try:
            if self.is_element_present(self.PROFILE_MENU_ITEM):
                self.click(self.PROFILE_MENU_ITEM)
                return self
        except Exception as e:
            logging.warning(f"使用Selenium点击个人中心菜单项失败: {e}")
            
        logging.error("无法找到个人中心菜单项")
        self.take_screenshot("profile_menu_item_not_found")
        raise Exception("无法找到个人中心菜单项")
    
    def open_profile_page(self):
        """
        打开个人中心页面
        """
        logging.info("打开个人中心页面")
        
        # 首先尝试通过点击菜单项打开个人中心页面
        try:
            self.click_profile_menu_item()
        except Exception as e:
            logging.warning(f"通过点击菜单项打开个人中心页面失败: {e}")
            # 如果点击失败，尝试直接访问URL
            self.open(self.PROFILE_PAGE_URL)
            logging.info(f"直接访问个人中心页面URL: {self.PROFILE_PAGE_URL}")
            
        return self
    
    def navigate_directly_to_profile(self):
        """
        直接通过URL导航到个人中心页面
        """
        logging.info(f"直接导航到个人中心页面: {self.PROFILE_PAGE_URL}")
        self.open(self.PROFILE_PAGE_URL)
        # 等待页面加载完成
        time.sleep(3)
        return self
    
    def click_edit_button(self):
        """
        点击编辑信息按钮 - 优化版本，直接使用JavaScript
        """
        logging.info("点击编辑信息按钮")
        
        # 直接使用JavaScript查找并点击按钮，不使用Selenium的查找方法
        result = self.driver.execute_script("""
        // 使用精确的XPath定位
        var editBtn = document.evaluate("/html/body/div[1]/div/div[2]/div[2]/div/div[1]/div[1]/div/button", 
                                      document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
        if (editBtn) {
            editBtn.click();
            return true;
        }
        
        // 如果精确XPath失败，尝试查找包含"编辑信息"文本的按钮
        var buttons = document.querySelectorAll('button');
        for (var i = 0; i < buttons.length; i++) {
            if (buttons[i].textContent.includes('编辑信息')) {
                buttons[i].click();
                return true;
            }
        }
        
        return false;
        """)
        
        if result:
            logging.info("成功点击编辑信息按钮")
            return self
        
        # 如果JavaScript方法失败，尝试使用Selenium方法
        logging.warning("JavaScript点击编辑信息按钮失败，尝试使用Selenium方法")
        try:
            button = self.find_element(self.EDIT_INFO_BUTTON)
            self.driver.execute_script("arguments[0].click();", button)
            logging.info("使用Selenium成功点击编辑信息按钮")
            return self
        except Exception as e:
            logging.error(f"点击编辑信息按钮失败: {e}")
            self.take_screenshot("edit_button_not_found")
            raise Exception("无法找到或点击编辑信息按钮")
    
    def click_save_button(self):
        """
        点击保存按钮 - 优化版本，直接使用JavaScript
        """
        logging.info("点击保存按钮")
        
        # 直接使用JavaScript查找并点击按钮
        result = self.driver.execute_script("""
        // 查找包含"保存"文本的按钮
        var buttons = document.querySelectorAll('button');
        for (var i = 0; i < buttons.length; i++) {
            if (buttons[i].textContent.includes('保存')) {
                buttons[i].click();
                return true;
            }
        }
        
        // 如果按文本查找失败，尝试使用XPath
        var saveBtn = document.evaluate("//button[.//span[contains(text(), '保存')]]", 
                                      document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
        if (saveBtn) {
            saveBtn.click();
            return true;
        }
        
        return false;
        """)
        
        if result:
            logging.info("成功点击保存按钮")
            return self
        
        # 如果JavaScript方法失败，尝试使用Selenium方法
        logging.warning("JavaScript点击保存按钮失败，尝试使用Selenium方法")
        try:
            button = self.find_element(self.SAVE_BUTTON)
            self.driver.execute_script("arguments[0].click();", button)
            logging.info("使用Selenium成功点击保存按钮")
            return self
        except Exception as e:
            logging.error(f"点击保存按钮失败: {e}")
            self.take_screenshot("save_button_not_found")
            raise Exception("无法找到或点击保存按钮")
    
    def click_cancel_button(self):
        """
        点击取消按钮 - 优化版本
        """
        logging.info("点击取消按钮")
        
        # 直接使用JavaScript查找并点击按钮
        self.driver.execute_script("""
        var buttons = document.querySelectorAll('button');
        for (var i = 0; i < buttons.length; i++) {
            if (buttons[i].textContent.includes('取消')) {
                buttons[i].click();
                break;
            }
        }
        """)
        
        return self
    
    def enter_name(self, name):
        """
        输入姓名
        
        Args:
            name: 要输入的姓名
        """
        logging.info(f"输入姓名: {name}")
        self.input_text(self.NAME_INPUT, name)
        return self
    
    def enter_email(self, email):
        """
        输入邮箱
        
        Args:
            email: 要输入的邮箱
        """
        logging.info(f"输入邮箱: {email}")
        self.input_text(self.EMAIL_INPUT, email)
        return self
    
    def enter_phone(self, phone):
        """
        输入手机号
        
        Args:
            phone: 要输入的手机号
        """
        logging.info(f"输入手机号: {phone}")
        self.input_text(self.PHONE_INPUT, phone)
        return self
    
    def select_gender(self, gender):
        """
        选择性别
        
        Args:
            gender: 性别，'男' 或 '女'
        """
        logging.info(f"选择性别: {gender}")
        
        # 使用JavaScript直接选择性别
        if gender == '男':
            self.driver.execute_script("""
            var maleRadio = document.evaluate("//span[text()='男']/preceding-sibling::span", 
                                           document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            if (maleRadio) {
                maleRadio.click();
            }
            """)
        elif gender == '女':
            self.driver.execute_script("""
            var femaleRadio = document.evaluate("//span[text()='女']/preceding-sibling::span", 
                                             document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            if (femaleRadio) {
                femaleRadio.click();
            }
            """)
        else:
            logging.warning(f"不支持的性别选项: {gender}")
            
        return self
    
    def get_name(self):
        """
        获取姓名输入框的值
        
        Returns:
            姓名
        """
        return self.find_element(self.NAME_INPUT).get_attribute("value")
    
    def get_email(self):
        """
        获取邮箱输入框的值
        
        Returns:
            邮箱
        """
        return self.find_element(self.EMAIL_INPUT).get_attribute("value")
    
    def get_phone(self):
        """
        获取手机号输入框的值
        
        Returns:
            手机号
        """
        return self.find_element(self.PHONE_INPUT).get_attribute("value")
    
    def get_gender(self):
        """
        获取选中的性别
        
        Returns:
            性别，'男' 或 '女'
        """
        try:
            male_radio = self.find_element(self.MALE_RADIO)
            if male_radio.is_selected() or 'is-checked' in male_radio.get_attribute("class"):
                return '男'
        except:
            pass
            
        try:
            female_radio = self.find_element(self.FEMALE_RADIO)
            if female_radio.is_selected() or 'is-checked' in female_radio.get_attribute("class"):
                return '女'
        except:
            pass
            
        return None
    
    def update_profile(self, name, email, phone, gender):
        """
        更新个人信息
        
        Args:
            name: 姓名
            email: 邮箱
            phone: 手机号
            gender: 性别，'男' 或 '女'
        """
        logging.info(f"更新个人信息: 姓名={name}, 邮箱={email}, 手机号={phone}, 性别={gender}")
        return (self
                .click_edit_button()
                .enter_name(name)
                .enter_email(email)
                .enter_phone(phone)
                .select_gender(gender)
                .click_save_button())
    
    def enter_old_password(self, password):
        """
        输入原密码
        
        Args:
            password: 原密码
        """
        logging.info("输入原密码")
        self.input_text(self.OLD_PASSWORD_INPUT, password)
        return self
    
    def enter_new_password(self, password):
        """
        输入新密码
        
        Args:
            password: 新密码
        """
        logging.info("输入新密码")
        self.input_text(self.NEW_PASSWORD_INPUT, password)
        return self
    
    def enter_confirm_password(self, password):
        """
        输入确认密码
        
        Args:
            password: 确认密码
        """
        logging.info("输入确认密码")
        self.input_text(self.CONFIRM_PASSWORD_INPUT, password)
        return self
    
    def click_change_password_button(self):
        """
        点击修改密码按钮
        """
        logging.info("点击修改密码按钮")
        self.click(self.CHANGE_PASSWORD_BUTTON)
        return self
    
    def change_password(self, old_password, new_password, confirm_password=None):
        """
        修改密码
        
        Args:
            old_password: 原密码
            new_password: 新密码
            confirm_password: 确认密码，默认与新密码相同
        """
        logging.info("修改密码")
        if confirm_password is None:
            confirm_password = new_password
            
        return (self
                .enter_old_password(old_password)
                .enter_new_password(new_password)
                .enter_confirm_password(confirm_password)
                .click_change_password_button())
    
    def get_success_message(self):
        """
        获取成功消息
        
        Returns:
            成功消息文本
        """
        if self.is_element_present(self.SUCCESS_MESSAGE):
            return self.get_text(self.SUCCESS_MESSAGE)
        return ""
    
    def get_error_message(self):
        """
        获取错误消息
        
        Returns:
            错误消息文本列表
        """
        try:
            # 首先检查表单错误信息（输入框下方的验证错误）
            error_elements = self.find_elements(self.FORM_ERROR_MESSAGE)
            error_messages = [element.text for element in error_elements if element.text.strip()]
            
            # 如果有表单错误信息，直接返回
            if error_messages:
                logging.info(f"获取到表单错误信息: {error_messages}")
                return error_messages
            
            # 其次检查全局错误信息（顶部弹出的消息）
            if self.is_element_present(self.ERROR_MESSAGE):
                global_error = self.get_text(self.ERROR_MESSAGE)
                if global_error:
                    logging.info(f"获取到全局错误信息: {global_error}")
                    return [global_error]
            
            # 如果没有找到任何错误信息，返回空列表
            logging.warning("未找到任何错误信息")
            return []
        except Exception as e:
            logging.error(f"获取错误信息失败: {e}")
            return []
    
    def is_update_successful(self):
        """
        检查更新是否成功
        
        Returns:
            布尔值，表示更新是否成功
        """
        success_message = self.get_success_message()
        return "更新成功" in success_message or "修改成功" in success_message 